home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / AppsToGo / DTS.Draw / TPieObj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  15.4 KB  |  570 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        TPieObj.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1992-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19. /* See the files "=How to write your app" and "=Using TreeObj.c" for information
  20. ** on this function. */
  21.  
  22. /* This file implements the messages for the pie object.  Many of the messages
  23. ** can be handled by the rect object, as they deal with a rect structure.  Only
  24. ** a few of them are pie-specific. */
  25.  
  26. /* We have a custom hit-test handler here because there are additional sizing
  27. ** grabbers for the pie object.  The other objects just have grabbers at the
  28. ** corners.  A pie object also has grabber objects to adjust the "pie-slice". */
  29.  
  30.  
  31.  
  32. /*****************************************************************************/
  33.  
  34.  
  35.  
  36. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  37. #include "App.protos.h"        /* Get the prototypes for the application.        */
  38.  
  39. #ifndef __OSEVENTS__
  40. #include <OSEvents.h>
  41. #endif
  42.  
  43. #ifndef __OSUTILS__
  44. #include <OSUtils.h>
  45. #endif
  46.  
  47. #ifndef __QUICKDRAW__
  48. #include <Quickdraw.h>
  49. #endif
  50.  
  51. #ifndef __TREEOBJ2__
  52. #include "TreeObj2.h"
  53. #endif
  54.  
  55. #ifndef __UTILITIES__
  56. #include "Utilities.h"
  57. #endif
  58.  
  59.  
  60.  
  61. static OSErr    PieLayerProc(LayerObj theLayer, short message);
  62.  
  63.  
  64.  
  65. /*****************************************************************************/
  66.  
  67.  
  68.  
  69. static PieObjPeek    *gMWERKSDebug;
  70.     /* For Metroweks debugging of AppsToGo "objects", you need an instance of the
  71.     ** same type you wish to view it in the debugger.  Now we have an instance. */
  72.  
  73.  
  74.  
  75. /*****************************************************************************/
  76. /*****************************************************************************/
  77.  
  78. #ifdef applec
  79. #pragma segment DTSDrawSeg2
  80. #endif
  81.  
  82. /*****************************************************************************/
  83. /*****************************************************************************/
  84.  
  85.  
  86.  
  87. long    TPieObj(TreeObjHndl hndl, short message, long data)
  88. {
  89.     ClickInfo    *click;
  90.     Rect        rct;
  91.     TreeObjHndl    hhndl;
  92.     RgnHandle    rgn, oldClip, newClip, accumRgn;
  93.     short        arcs, arcl, arcs2, arcl2, diff, i, angle, h, w;
  94.     Point        pt, where, curMouse;
  95.     long        flip, newSize;
  96.     LayerObj    pieLayer;
  97.     EventRecord    option;
  98.     RGBColor    rgb, rgb2;
  99. #if VH_VERSION
  100.     char        *cptr;
  101. #endif
  102.  
  103.     switch (message) {
  104.         case INITMESSAGE:
  105.             TRectObj(hndl, message, data);
  106.             mDerefPie(hndl)->arcStart  = 0;
  107.             mDerefPie(hndl)->arcLength = 360;
  108.             break;
  109.  
  110.         case FREEMESSAGE:
  111.         case COPYMESSAGE:
  112.         case UNDOMESSAGE:
  113.         case CONVERTMESSAGE:
  114.         case FREADMESSAGE:
  115.         case FWRITEMESSAGE:
  116.         case HREADMESSAGE:
  117.         case HWRITEMESSAGE:
  118.         case GETOBJRECTMESSAGE:
  119.         case SECTOBJRECTMESSAGE:
  120.         case KEYMESSAGE:
  121.         case SETSELECTMESSAGE:
  122.         case GETSELECTMESSAGE:
  123.         case COMPAREMESSAGE:
  124.             return(TRectObj(hndl, message, data));
  125.             break;
  126.  
  127.         case GETBBOXMESSAGE:
  128.             return(TLineObj(hndl, message, data));
  129.             break;
  130.  
  131.         case HITTESTMESSAGE:
  132.             click = (ClickInfo *)data;
  133.             hhndl = (TreeObjHndl)TRectObj(hndl, message, data);
  134.                 /* We must call TRectObj::HITTESTMESSAGE to set some static
  135.                 ** variables that TRectObj::SELECTOBJMESSAGE uses. */
  136.             if ((!hhndl) && (click->message == HITTESTGRABBER)) {
  137.                 if (mDerefRoot(GetRootHndl(hndl))->numSelected == 1) {
  138.                     if (mDerefPie(hndl)->selected) {
  139.                         rct   = mDerefPie(hndl)->arc;
  140.                         where = click->localEvent.where;
  141.                         InsetRect(&rct, -4, -4);
  142.                         if (PtInRect(where, &rct)) {
  143.                             GetMouse(&curMouse);
  144.                             for (i = 0; i < 2; ++i) {
  145.                                 pt = (i) ? mDerefPie(hndl)->arcEnd : mDerefPie(hndl)->arcBegin;
  146.                                 rct.bottom = (rct.top  = pt.v - 3) + 6;
  147.                                 rct.right  = (rct.left = pt.h - 3) + 6;
  148.                                 if (PtInRect(where, &rct)) {
  149.                                     click->localEvent.where = pt;
  150.                                     click->offset.h         = pt.h - curMouse.h;
  151.                                     click->offset.v         = pt.v - curMouse.v;
  152.                                     click->oldFlip          = 0;
  153.                                     click->newFlip          = 0;
  154.                                     click->grabber          = 5 + i;
  155.                                     hhndl = hndl;
  156.                                     break;
  157.                                 }
  158.                             }
  159.                         }
  160.                     }
  161.                 }
  162.             }
  163.             return((long)hhndl);
  164.             break;
  165.  
  166.         case GETRGNMESSAGE:
  167.             rgn      = NewRgn();
  168.             accumRgn = (RgnHandle)data;
  169.             if (accumRgn)
  170.                 if (GetHandleSize((Handle)accumRgn) > 10000)
  171.                     return((long)rgn);
  172.             NewLayer(&pieLayer, nil, PieLayerProc, nil, 0, (long)hndl);
  173.             if (pieLayer) {
  174.                 SetLayerWorld(pieLayer);
  175.                 TPieObj(hndl, DRAWMESSAGE, DRAWMASK);
  176.                 if (gQDVersion)
  177.                     BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  178.                 else
  179.                     BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  180.                 ResetLayerWorld(pieLayer);
  181.                 DisposeLayer(pieLayer);
  182.             }
  183.             if (accumRgn)
  184.                 UnionRgn(rgn, accumRgn, accumRgn);
  185.             return((long)rgn);
  186.             break;
  187.  
  188.         case SETOBJRECTMESSAGE:
  189.             TRectObj(hndl, message, data);
  190.             CalcPiePoints(hndl);
  191.             break;
  192.  
  193.         case DRAWMESSAGE:
  194.             rct = mDerefPie(hndl)->arc;
  195.             h   = mDerefCommon(hndl)->penHeight;
  196.             w   = mDerefCommon(hndl)->penWidth;
  197.             PenSize(w, h);
  198.             if (!EmptyRect(&rct)) {
  199.                 arcs = mDerefPie(hndl)->arcStart;
  200.                 arcl = mDerefPie(hndl)->arcLength;
  201.                 switch (data) {
  202.                     case DRAWOBJ:
  203.                         GetClip(oldClip = NewRgn());
  204.                         newClip = (RgnHandle)TOvalObj(hndl, GETRGNMESSAGE, 0);
  205.                         if (newClip)
  206.                             SetClip(newClip);
  207.                         if (gQDVersion)
  208.                             GetForeColor(&rgb);
  209.                         ForeColor(whiteColor);
  210.                         if (gQDVersion) {
  211.                             rgb2 = mDerefPie(hndl)->contentColor;
  212.                             RGBForeColor(&rgb2);
  213.                         }
  214.                         PaintArc(&rct, arcs, arcl);
  215.                         ForeColor(blackColor);
  216.                         if (gQDVersion) {
  217.                             rgb2 = mDerefPie(hndl)->borderColor;
  218.                             RGBForeColor(&rgb2);
  219.                         }
  220.                         FrameArc(&rct, arcs, arcl);
  221.                         pt = mDerefPie(hndl)->arcBegin;
  222.                         MoveTo(pt.h - (w / 2), pt.v - (w / 2));
  223.                         pt = mDerefPie(hndl)->center;
  224.                         LineTo(pt.h - (w / 2), pt.v - (w / 2));
  225.                         pt = mDerefPie(hndl)->arcEnd;
  226.                         LineTo(pt.h - (w / 2), pt.v - (w / 2));
  227.                         if (gQDVersion)
  228.                             RGBForeColor(&rgb);
  229.                         SetClip(oldClip);
  230.                         DisposeRgn(oldClip);
  231.                         if (newClip)
  232.                             DisposeRgn(newClip);
  233.                         break;
  234.                     case ERASEOBJ:
  235.                         EraseArc(&rct, arcs, arcl);
  236.                         break;
  237.                     case DRAWSELECT:
  238.                         if (mDerefPie(hndl)->selected) {
  239.                             TRectObj(hndl, message, data);
  240.                             for (i = 0; i < 2; ++i) {
  241.                                 pt = (i) ? mDerefPie(hndl)->arcEnd : mDerefPie(hndl)->arcBegin;
  242.                                 rct.bottom = (rct.top  = pt.v - 3) + 6;
  243.                                 rct.right  = (rct.left = pt.h - 3) + 6;
  244.                                 InvertRect(&rct);
  245.                                 arcl = mDerefPie(hndl)->arcLength;
  246.                                 if ((arcl == -360) || (!arcl) || (arcl == 360)) break;
  247.                             }
  248.                         }
  249.                         break;
  250.                     case DRAWGHOST:
  251.                         PenMode(patXor);
  252.                         FrameArc(&rct, arcs, arcl);
  253.                         break;
  254.                     case DRAWMASK:
  255.                         FillArc(&rct, arcs, arcl, (ConstPatternParam)&qd.black);
  256.                         FrameArc(&rct, arcs, arcl);
  257.                         pt = mDerefPie(hndl)->arcBegin;
  258.                         MoveTo(pt.h - (w / 2), pt.v - (w / 2));
  259.                         pt = mDerefPie(hndl)->center;
  260.                         LineTo(pt.h - (w / 2), pt.v - (w / 2));
  261.                         pt = mDerefPie(hndl)->arcEnd;
  262.                         LineTo(pt.h - (w / 2), pt.v - (w / 2));
  263.                         break;
  264.                 }
  265.             }
  266.             PenNormal();
  267.             break;
  268.  
  269.         case PRINTMESSAGE:
  270.             TPieObj(hndl, DRAWMESSAGE, DRAWOBJ);
  271.             break;
  272.  
  273. #if VH_VERSION
  274.         case VHMESSAGE:
  275.             cptr = ((VHFormatDataPtr)data)->data;
  276.             ccatchr(cptr, 13, 2);
  277.             ccat   (cptr, "$10: TPieObj:");
  278.             ccatchr(cptr, 13, 1);
  279.             ccat   (cptr, "  $00: selected = ");
  280.             ccatdec(cptr, mDerefPie(hndl)->selected);
  281.             ccatchr(cptr, 13, 1);
  282.             rct = mDerefPie(hndl)->arc;
  283.             ccat   (cptr, "  $02: pie      = (");
  284.             ccatdec(cptr, rct.top);
  285.             ccat   (cptr, ",");
  286.             ccatdec(cptr, rct.left);
  287.             ccat   (cptr, ",");
  288.             ccatdec(cptr, rct.bottom);
  289.             ccat   (cptr, ",");
  290.             ccatdec(cptr, rct.right);
  291.             ccat   (cptr, ")");
  292.             ccatchr(cptr, 13, 1);
  293.             ccat   (cptr, "  $0A: arcStart  = ");
  294.             ccatdec(cptr, mDerefPie(hndl)->arcStart);
  295.             ccatchr(cptr, 13, 1);
  296.             ccat   (cptr, "  $0C: arcLength = ");
  297.             ccatdec(cptr, mDerefPie(hndl)->arcLength);
  298.             ccatchr(cptr, 13, 1);
  299.             ccat   (cptr, "  $0E: center    = (");
  300.             ccatdec(cptr, mDerefPie(hndl)->center.v);
  301.             ccat   (cptr, ",");
  302.             ccatdec(cptr, mDerefPie(hndl)->center.h);
  303.             ccat   (cptr, ")");
  304.             ccatchr(cptr, 13, 1);
  305.             ccat   (cptr, "  $12: arcBegin  = (");
  306.             ccatdec(cptr, mDerefPie(hndl)->arcBegin.v);
  307.             ccat   (cptr, ",");
  308.             ccatdec(cptr, mDerefPie(hndl)->arcBegin.h);
  309.             ccat   (cptr, ")");
  310.             ccatchr(cptr, 13, 1);
  311.             ccat   (cptr, "  $16: arcEnd    = (");
  312.             ccatdec(cptr, mDerefPie(hndl)->arcEnd.v);
  313.             ccat   (cptr, ",");
  314.             ccatdec(cptr, mDerefPie(hndl)->arcEnd.h);
  315.             ccat   (cptr, ")");
  316.             ccatchr(cptr, 13, 1);
  317.             return(true);
  318.             break;
  319. #endif
  320.  
  321.         case CLICKMESSAGE:
  322.             TRectObj(hndl, message, data);
  323.             click = (ClickInfo *)data;
  324.             if (click->message == CLICKDRAG) {
  325.                 AddPt(click->offset, &mDerefPie(hndl)->center);
  326.                 AddPt(click->offset, &mDerefPie(hndl)->arcBegin);
  327.                 AddPt(click->offset, &mDerefPie(hndl)->arcEnd);
  328.             }
  329.             break;
  330.  
  331.         case SIZEMESSAGE:
  332.             click = (ClickInfo *)data;
  333.             if (click->grabber <= 4) {
  334.                 newSize = TRectObj(hndl, message, data);
  335.                 click = (ClickInfo *)data;
  336.                 flip = (click->oldFlip ^ click->newFlip);
  337.                 if (flip) {
  338.                     arcs = mDerefPie(hndl)->arcStart;
  339.                     arcl = mDerefPie(hndl)->arcLength;
  340.                     if (flip & VFLIPOBJ) {
  341.                         arcs -= (i = (arcs < 180) ? 0 : 180);
  342.                         arcs = 180 - arcs;
  343.                         arcl = -arcl;
  344.                         arcs += i;
  345.                     }
  346.                     if (flip & HFLIPOBJ) {
  347.                         arcs = 360 - arcs;
  348.                         arcl = -arcl;
  349.                     }
  350.                     mDerefPie(hndl)->arcStart  = arcs;
  351.                     mDerefPie(hndl)->arcLength = arcl;
  352.                 }
  353.                 CalcPiePoints(hndl);
  354.                 return(newSize);
  355.             }
  356.  
  357.             GetMouse(&curMouse);
  358.             curMouse.h += click->offset.h;
  359.             curMouse.v += click->offset.v;
  360.             rct = mDerefPie(hndl)->arc;
  361.  
  362.             arcs = arcs2 = mDerefPie(hndl)->arcStart;
  363.             arcl = arcl2 = mDerefPie(hndl)->arcLength;
  364.  
  365.             PtToAngle(&rct, curMouse, &angle);
  366.  
  367.             if (click->grabber == 6) {        /* Handle 2nd grabber as reverse first grabber case. */
  368.                 click->grabber = 5;
  369.                 arcs += arcl;
  370.                 arcl  = -arcl;
  371.                 while (arcs >  360) arcs -= 360;
  372.                 while (arcs <    0) arcs += 360;
  373.             }
  374.  
  375.             diff = angle - arcs;
  376.             arcs = angle;
  377.             OSEventAvail(nullEvent, &option);
  378.             if (!(option.modifiers & shiftKey)) {
  379.                 while (diff >  180) diff -= 360;        /* Force 1 change to be less than 180. */
  380.                 while (diff < -180) diff += 360;
  381.                 arcl   -= diff;
  382.                 while (arcl >  360) arcl -= 360;
  383.                 while (arcl < -360) arcl += 360;
  384.             }
  385.  
  386.             if ((arcs != arcs2) || (arcl != arcl2)) {
  387.                 mDerefPie(hndl)->arcStart  = arcs;
  388.                 mDerefPie(hndl)->arcLength = arcl;
  389.                 CalcPiePoints(hndl);
  390.                 return(true);
  391.             }
  392.             break;
  393.  
  394.         default:
  395.             break;
  396.     }
  397.  
  398.     return(noErr);
  399. }
  400.  
  401.  
  402.  
  403. /*****************************************************************************/
  404.  
  405.  
  406.  
  407. OSErr    CalcPiePoints(TreeObjHndl hndl)
  408. {
  409.     OSErr        err;
  410.     Rect        rct;
  411.     short        arcs, arcl, i, angle;
  412.     RgnHandle    rgn;
  413.     Point        pt;
  414.     long        ll;
  415.     LayerObj    pieLayer;
  416.  
  417.     err = NewLayer(&pieLayer, nil, PieLayerProc, nil, 0, (long)hndl);
  418.     if (err) return(err);
  419.  
  420.     rct  = mDerefPie(hndl)->arc;
  421.     arcs = mDerefPie(hndl)->arcStart;
  422.     arcl = mDerefPie(hndl)->arcLength;
  423.  
  424.     SetLayerWorld(pieLayer);
  425.     rgn = NewRgn();
  426.  
  427.     EraseRect(&rct);
  428.     FillArc(&rct, 90, 90, (ConstPatternParam)&qd.black);
  429.  
  430.     if (gQDVersion)
  431.         BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  432.     else
  433.         BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  434.     pt = *(Point *)(&(*rgn)->rgnBBox);
  435.     ll = PinRect(&rct, pt);
  436.     pt = *(Point *)≪
  437.     mDerefPie(hndl)->center = pt;
  438.  
  439.     for (i = 0; i < 2; ++i) {
  440.         angle = (i) ? (arcs + arcl) : (arcs);
  441.         while (angle < 0)    angle += 360;
  442.         while (angle >= 360) angle -= 360;
  443.         EraseRect(&rct);
  444.         if (angle < 90) {
  445.             FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
  446.             if (gQDVersion)
  447.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  448.             else
  449.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  450.             pt.v = (*rgn)->rgnBBox.top;
  451.             EraseRect(&rct);
  452.             FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
  453.             if (gQDVersion)
  454.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  455.             else
  456.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  457.             pt.h = (*rgn)->rgnBBox.right;
  458.             if (angle > 45)
  459.                 --pt.h;
  460.         }
  461.         if ((angle >= 90) && (angle < 180)) {
  462.             FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
  463.             if (gQDVersion)
  464.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  465.             else
  466.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  467.             pt.h = (*rgn)->rgnBBox.right;
  468.             EraseRect(&rct);
  469.             FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
  470.             if (gQDVersion)
  471.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  472.             else
  473.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  474.             pt.v = (*rgn)->rgnBBox.bottom;
  475.             if (angle < 135)
  476.                 --pt.h;
  477.             else
  478.                 --pt.v;
  479.         }
  480.         if ((angle >= 180) && (angle < 270)) {
  481.             FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
  482.             if (gQDVersion)
  483.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  484.             else
  485.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  486.             pt.v = (*rgn)->rgnBBox.bottom;
  487.             EraseRect(&rct);
  488.             FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
  489.             if (gQDVersion)
  490.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  491.             else
  492.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  493.             pt.h = (*rgn)->rgnBBox.left;
  494.             if (angle < 225)
  495.                 --pt.v;
  496.         }
  497.         if (angle >= 270) {
  498.             FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
  499.             if (gQDVersion)
  500.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  501.             else
  502.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  503.             pt.h = (*rgn)->rgnBBox.left;
  504.             EraseRect(&rct);
  505.             FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
  506.             if (gQDVersion)
  507.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  508.             else
  509.                 BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
  510.             pt.v = (*rgn)->rgnBBox.top;
  511.         }
  512.         ll = PinRect(&rct, pt);
  513.         pt = *(Point *)≪
  514.         (i) ? (mDerefPie(hndl)->arcEnd = pt) : (mDerefPie(hndl)->arcBegin = pt);
  515.     }
  516.  
  517.     DisposeRgn(rgn);
  518.     ResetLayerWorld(pieLayer);
  519.     DisposeLayer(pieLayer);
  520.     return(noErr);
  521. }
  522.  
  523.  
  524.  
  525. /*****************************************************************************/
  526.  
  527.  
  528.  
  529. static OSErr    PieLayerProc(LayerObj theLayer, short message)
  530. {
  531.     OSErr        err;
  532.     TreeObjHndl    pie;
  533.     Rect        rct;
  534.     CGrafPtr    keepPort;
  535.     GDHandle    keepGDevice;
  536.     GWorldPtr    layerWorld;
  537.  
  538.     switch (message) {
  539.         case kLayerInit:
  540.             err = noErr;
  541.             if (theLayer) {
  542.                 if (!(*theLayer)->layerPort) {
  543.                     pie = (TreeObjHndl)(*theLayer)->layerData;
  544.                     rct = mDerefPie(pie)->arc;
  545.                     GetGWorld(&keepPort, &keepGDevice);        /* Keep the GWorld. */
  546.                     err = NewGWorld(&layerWorld, 1, &rct, nil, nil, 0);
  547.                     if (err == noErr) {
  548.                         (*theLayer)->layerOwnsPort = true;
  549.                         SetPort((*theLayer)->layerPort = (GrafPtr)layerWorld);
  550.                         SetOrigin(rct.left, rct.top);
  551.                         EraseRect(&rct);
  552.                     }
  553.                     SetGWorld(keepPort, keepGDevice);        /* Restore the kept GWorld. */
  554.                 }
  555.             }
  556.             else err = paramErr;
  557.             break;
  558.  
  559.         default:
  560.             err = DefaultLayerProc(theLayer, message);
  561.                 /* Default behavior for everything else. */
  562.             break;
  563.     }
  564.  
  565.     return(err);
  566. }
  567.  
  568.  
  569.  
  570.